//
//  GameScene.swift
//  flipbird
//
//  Created by Maxwell on 11/12/18.
//  Copyright © 2018 Maxwell. All rights reserved.
//

import SpriteKit
import GameplayKit

class GameScene: SKScene {
   
    var land1 = SKSpriteNode(imageNamed: "land")
    var land2 = SKSpriteNode(imageNamed: "land")
    
    let birdCategory:UInt32 = 0x1 << 0
    let pipeCategory:UInt32 = 0x1 << 1
    let floorCategory:UInt32 = 0x1 << 2
    let uiheight = UIApplication.shared.statusBarFrame.height
    
    lazy var bird:SKSpriteNode = {
        var bird = SKSpriteNode(imageNamed: "bird-01")
        bird.physicsBody = SKPhysicsBody(circleOfRadius: bird.size.width/2)
        bird.physicsBody?.isDynamic = true
        bird.physicsBody?.allowsRotation = false
        bird.physicsBody?.categoryBitMask = birdCategory
        bird.position = CGPoint(x: self.size.width * 0.5, y: self.size.height * 0.5)
        return bird
    }()
    
    
    enum GameStatus{
        case initial
        case running
        case gameover
    }
    
    var status:GameStatus = .initial
    
   
    
    override init(size: CGSize) {
        super.init(size: size)
        
        physicsWorld.gravity = CGVector(dx: 0.0, dy: -0.1)
        
        backgroundColor = SKColor(red: 80/255.0, green: 192.0/255.0, blue: 203.0/255.0, alpha: 1.0)
        

        land1.anchorPoint = CGPoint(x: 0, y: 0)
        land1.position = CGPoint(x: 0, y: 0)
        addChild(land1)
        
        land2.anchorPoint = CGPoint(x: 0, y: 0)
        land2.position = CGPoint(x: land1.size.width, y: 0)
        addChild(land2)
        
       
        
        addChild(bird)
        birdFly()
        startCreatRandomPipeAction()
        
        
    }
    
    func gameInitial(){
        
        status = .initial
    }
    
    func gameRunning(){
        
        status = .running
    }
    
    func gameOver(){
        
        birdStopFly()
        stopCreateRandomPipesAction()
        status = .gameover
    }
    
    func moveScene(){
        land1.position = CGPoint(x: land1.position.x - 1, y: land1.position.y)
        land2.position = CGPoint(x: land2.position.x - 1, y: land2.position.y)
        
        if land1.position.x < -(land1.size.width * 0.5){
            land2.position = CGPoint(x: 0, y: land2.position.y)
            land1.position = CGPoint(x: land2.position.x + land2.size.width, y: land1.position.y)
            
        }
        
        if land2.position.x < -(land2.size.width * 0.5){
            land1.position = CGPoint(x: 0, y: land1.position.y)
            land2.position = CGPoint(x: land1.position.x + land1.size.width, y: land2.position.y)
        }
        //场景中有许多个pipe
        for pipeNode in self.children where pipeNode.name == "Pipe" {
            if let pipeSprite = pipeNode as? SKSpriteNode{
                pipeSprite.position = CGPoint(x: pipeSprite.position.x - 1, y: pipeSprite.position.y)
                if pipeSprite.position.x < -pipeSprite.size.width * 0.5 {
                    pipeSprite.removeFromParent()
                }
            }
    
        }
    }
    
    func addPipes(upSize:CGSize,downSize:CGSize){
        let upPipeTexture = SKTexture(imageNamed: "PipeUp")
        let upPipeNode = SKSpriteNode(texture: upPipeTexture, size: upSize)
        upPipeNode.name = "Pipe"
        upPipeNode.position = CGPoint(x:self.size.width + upPipeNode.size.width*0.5, y:self.size.height - upPipeNode.size.height*0.5)
        upPipeNode.physicsBody = SKPhysicsBody(texture: upPipeTexture, size: upSize)
        upPipeNode.physicsBody?.isDynamic = false
        upPipeNode.physicsBody?.categoryBitMask = pipeCategory
        addChild(upPipeNode)
        
        let downPipeTexture = SKTexture(imageNamed: "PipeDown")
        let downPipeNode = SKSpriteNode(texture: downPipeTexture, size: downSize)
        downPipeNode.name = "Pipe"
        
        downPipeNode.physicsBody = SKPhysicsBody(texture: downPipeTexture, size: downSize)
        downPipeNode.physicsBody?.isDynamic = false
        downPipeNode.physicsBody?.categoryBitMask = pipeCategory
        
        downPipeNode.position = CGPoint(x:self.size.width + downPipeNode.size.width*0.5, y:land1.size.height + downPipeNode.size.height * 0.5)
        addChild(downPipeNode)
    }
    
    func createRandomPipes(){
        let height = self.size.height - uiheight - land1.size.height
        let pipeGap = CGFloat(arc4random_uniform(UInt32(bird.size.height))) + bird.size.height*2.5
        let pipeWidth = CGFloat(60.0)
        let upPipeHeight = CGFloat(arc4random_uniform(UInt32(height-pipeGap)))
        let downPipeHeight = height - pipeGap - upPipeHeight
        addPipes(upSize: CGSize(width: pipeWidth, height: upPipeHeight), downSize: CGSize(width: pipeWidth, height: downPipeHeight))
        
    }
    
    func startCreatRandomPipeAction(){
        let waitAct = SKAction.wait(forDuration: 3.5,withRange:1.0)
        let generateAction = SKAction.run{
            self.createRandomPipes()
        }
        run(SKAction.repeatForever(SKAction.sequence([waitAct,generateAction])), withKey: "createPipe")
    }
    
    func stopCreateRandomPipesAction(){
        self.removeAction(forKey: "createPipe")
    }
    
    func birdFly(){
        let flyAction = SKAction.animate(with: [SKTexture(imageNamed: "bird-01"),
                                                SKTexture(imageNamed: "bird-02"),
                                                SKTexture(imageNamed: "bird-03"),
                                                SKTexture(imageNamed: "bird-04")], timePerFrame: 0.15)
        bird.run(SKAction.repeatForever(flyAction),withKey: "fly")
    }
    
    func birdStopFly(){
        bird.removeAction(forKey: "fly")
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func didMove(to view: SKView) {
        
    }
    
    override func update(_ currentTime: TimeInterval) {
        if status != .gameover {
            moveScene()
        }
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        bird.physicsBody?.applyImpulse(CGVector(dx: 0.0, dy: 20.0))
    }
    
}
